class WndGrid : public Wnd
{
public:
	WndGrid(LPCTSTR WndText = TEXT(""), DWORD dwStyle = 0, 
		int x = CW_USEDEFAULT,  int y = 0,  int nWidth = CW_USEDEFAULT,  int nHeight = 0,
		HWND hWndParent = NULL,  HMENU hMenu = NULL,  HINSTANCE hInstance = Application::hInst, LPVOID lpParam = NULL);
protected:
	virtual ATOM MyRegisterClass(HINSTANCE hInstance);

	virtual BOOL isWndClassRegistered() {return isClassRegistered;}
	virtual void setWndClassRegistered() {isClassRegistered = TRUE;}
	virtual LPCWSTR getWndClassName() {return wndClassName;}
	static BOOL isClassRegistered;
	static TCHAR wndClassName[MAX_LOADSTRING];
};

/* Custom Messages */
//#define MSG_GRID_ZOOMING			WM_USER+1
#define MSG_GRID_LBUTTONDOWN		WM_USER+2
#define MSG_GRID_REFRESH			WM_USER+3
#define MSG_GRID_INSERTROW			WM_USER+4
#define MSG_GRID_INSERTCOL			WM_USER+5
#define MSG_GRID_REMOVEROW			WM_USER+6
#define MSG_GRID_REMOVECOL			WM_USER+7
#define MSG_GRID_ONCOPY				WM_USER+8
#define MSG_GRID_ONCUT				WM_USER+9
#define MSG_GRID_ONPASTE			WM_USER+10
#define MSG_GRID_TEXTCOLOR			WM_USER+11
#define MSG_GRID_BACKCOLOR			WM_USER+12
#define MSG_GRID_STYLECLEAR			WM_USER+13
#define MSG_GRID_SELECTALL			WM_USER+14
#define MSG_GRID_GOTO				WM_USER+15
#define MSG_GRID_ALIGN				WM_USER+16
#define MSG_GRID_VALIGN				WM_USER+17
#define MSG_GRID_FONT				WM_USER+18
#define MSG_GRID_FONTATTR			WM_USER+19

class WndGridCtlr : public WndController
{
public:
	WndGridCtlr();
	static HWND GetEditBoxHwnd(){return hEditBox;}
	static void CheckToolBarButton();
protected:
	static LRESULT CALLBACK OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK OnPaint(HWND hWnd, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK OnSize(HWND hWnd, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK OnEraseBG(HWND hWnd, WPARAM wParam, LPARAM lParam);
	
	static LRESULT CALLBACK OnKeyDown(HWND hWnd, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK OnChar(HWND hWnd, WPARAM wParam, LPARAM lParam);
	
	static LRESULT CALLBACK OnMouseMove(HWND hWnd, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK OnMouseUp(HWND hWnd, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK OnMouseDown(HWND hWnd, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK OnMouseDouble(HWND hWnd, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK OnMouseRight(HWND hWnd, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK OnMouseWheel(HWND hWnd, WPARAM wParam, LPARAM lParam);
	
	static LRESULT CALLBACK OnVScroll(HWND hWnd, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK OnHScroll(HWND hWnd, WPARAM wParam, LPARAM lParam);

	static LRESULT CALLBACK RefreshGridData(HWND hWnd, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK InsertRow(HWND hWnd, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK InsertCol(HWND hWnd, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK RemoveRow(HWND hWnd, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK RemoveCol(HWND hWnd, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK OnCopy(HWND hWnd, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK OnCut(HWND hWnd, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK OnPaste(HWND hWnd, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK OnSetTextColor(HWND hWnd, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK OnSetBackColor(HWND hWnd, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK OnStyleClear(HWND hWnd, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK OnSelectAll(HWND hWnd, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK OnGoto(HWND hWnd, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK OnAlign(HWND hWnd, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK OnVAlign(HWND hWnd, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK OnFontSelect(HWND hWnd, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK OnFontAttr(HWND hWnd, WPARAM wParam, LPARAM lParam);

	static LRESULT CALLBACK EditBox(HWND hWnd, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK EditBoxProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

	
private:
	enum MOVING_TYPE {NONE, 
		COL_WIDTH, ROW_HEIGHT,
		ROW_SELECT, COL_SELECT, 
		CELL_SELECT};
	static MOVING_TYPE movingType;

	static int xChar, xCaps, yChar, xClient, yClient;
	// For mouse wheel logic
	static int iDeltaPerline, iAccumDelta;
	static ULONG ulScrollLines;
	static LRESULT CALLBACK scroll(HWND hWnd, int nBar, WPARAM wParam, LPARAM lParam);

	// selecting
	static void selectCell(HWND hWnd, CELLPOS& pos, bool multiCell);
	static void selectCol(HWND hWnd, COL_NUM iCol, bool multi);
	static void selectRow(HWND hWnd, ROW_NUM iRow, bool multi);

	// scroll Bar
	static void ResizeScrollBar(HWND hWnd);

	// private drawings
	static void drawGrid(HDC& hdc);
	static void drawHeaders(HDC& hdc, int * ColWidth, int * RowHeight, const int nCol, const int nRow, RECT& RegionRect);
	static void drawRowHeader(HDC& hdc, int * RowHeight, const int nRow, RECT& RegionRect);
	static void drawColHeader(HDC& hdc, int * ColWidth, const int nCol, RECT& RegionRect);
	static void drawLines(HDC& hdc, int * ColWidth, int * RowHeight, const int nCol, const int nRow);
	static void drawSelecting(HDC& hdc);
	static void drawRegion(HDC& hdc, RECT& RegionRect);
	static void drawRegionBorder(HDC& hdc, RECT& RegionRect);
	static void printContent(HDC& hdc);

	static HFONT MyCreateFont(HDC hdc, const TCHAR * szFaceName, int iAttributes);
	
	static void CheckMenu(HMENU hMenu);
	static void CheckMenuItem(HMENU hMenu, int nID, bool checked);

	// EditBox
	static void CreateEditBox(HWND hWnd, RECT rectCell, const CellDataItem* item = 0);
	static void HideEditBox();
	static HWND hEditBox;
	static WNDPROC EditProc;

	static SheetView SheetViewer;
	//static bool isEditMode;
};